package logic

import (
	"gameserver/entitydef"
	"gameserver/server/redisutil"
	"reflect"

	"gitee.com/night-tc/gobige/dbmanager"
	"gitee.com/night-tc/gobige/entity/props"
	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
)

//-------------------------------------------------------------------------
/* IDataBaseModel 接口 */
// KeyName 数据的唯一名字
func (this *Player) KeyName() string {
	return entitydef.PlayerByGameMDTableName
}

// GetPID 用户主键
func (this *Player) GetPID() uint64 {
	return this.GetDBID()
}

// TableName 拿到表名
func (this *Player) TableName() string {
	return entitydef.PlayerByGameMDTableName

}

// Marshal 序列化
func (this *Player) Marshal() ([]byte, error) {
	return nil, nil
}

// Unmarshal 反序列化
func (this *Player) Unmarshal(data []byte) error {
	return nil
}

// GetIsPartial 是否支持部分更新
func (this *Player) GetIsPartial() bool {
	return true
}

// IsDeleted 判断数据是否被删除
func (this *Player) IsDeleted() bool {
	return false
}

// SetDelete 标记数据为已删除
func (this *Player) SetDelete() {

}

// RevokeDelete 撤销删除
func (this *Player) RevokeDelete() {

}

/* IDataBaseModel 接口 */
//-------------------------------------------------------------------------
/* IServicePlayer 玩家服务接口 */

// OnLoadedAll 玩家所有数据加载完成
func (this *Player) OnLoadedAll() {
	// 发个标记消息给客户端，告诉它完成加载了，可以处理消息了
}

/* IServicePlayer 玩家服务接口 */
//-------------------------------------------------------------------------
/* IServicePlayer 玩家服务接口 */
// GetTableNames 返回系统模块需要的表名列表
func (this *Player) GetTableNames() []string {
	return []string{entitydef.PlayerByGameMDTableName}
}

// LoadDB 从DB获取数据，或从别的服获取数据后的加载方法
func (this *Player) LoadDB(lis map[string][]dbmanager.IDataBaseModel) {

	if tableli, ok := lis[entitydef.PlayerByGameMDTableName]; ok {
		for _, rowmd := range tableli {
			md := rowmd.(*entitydef.PlayerByGameMD)
			//赋值操作
			vmd := reflect.ValueOf(md).Elem()
			this.ForEachProp(func(p props.IProp) {
				fmd := vmd.FieldByName(p.GetName())
				if !fmd.IsValid() {
					return
				}
				p.SetDirty()
				p.LoadValue(fmd.Interface())
			})
		}
	}

	this.IsLoad = true
}

// LoadData 从Redis加载数据的方法
func (this *Player) LoadData(lis map[string][]dbmanager.IDataBaseModel) {

	if tableli, ok := lis[entitydef.PlayerByGameMDTableName]; ok {
		for _, rowmd := range tableli {
			md := rowmd.(*entitydef.PlayerByGameMD)
			//赋值操作
			vmd := reflect.ValueOf(md).Elem()
			this.ForEachProp(func(p props.IProp) {
				fmd := vmd.FieldByName(p.GetName())
				if !fmd.IsValid() {
					return
				}
				p.SetDirty()
				p.LoadValue(fmd.Interface())
			})
			this.ModuleBase.IsLoad = true
		}
	}
}

// InitLoaded 在LoadDB和LoadData成功后调用，用于填充数据后的初始化
func (this *Player) InitLoaded() {
	if !this.ModuleBase.GetIsLoaded() {
		return
	}
	if this.NttPlayerByGameDef.GetPlayerID() == 0 {
		this.NttPlayerByGameDef.SetPlayerID(this.GetDBID())
	}

	if this.NttPlayerByGameDef.GetLevel() == 0 {
		this.NttPlayerByGameDef.SetLevel(1)
	}
	if this.NttPlayerByGameDef.GetName() == "" {
		prd := redisutil.NewLoginPlayer(this.GetDBID())
		data, err := prd.GetInfo()
		if err != nil {
			logger.Warnf("callbackCreateEntityByStype pid:%d;nttid:%d;err:%s", this.GetDBID(), this.GetEntityID(), err)
			this.SetLoadFail()
			return
		}
		this.NttPlayerByGameDef.SetName(data[redisutil.LoginPlayer_Key_PlayerName])
	}
}

// SyncData 同步数据到客户端、Redis或DBServer
func (this *Player) SyncData() {

	this.ModuleBase.SyncData()

}

// AllDataSyncClient 将全量数据同步到客户端
func (this *Player) AllDataSyncClient() {
	if !this.IsLoad {
		return
	}
	propli := this.PackMRloeProps()
	msg := new(protomsg.SyncEntityProps)
	msg.Props = propli
	msg.EntityID = this.GetEntityID()
	msg.EntityType = this.GetType()
	_ = this.User.Post(global.ServerTypeClient, msg)
}
